package com.gitee.qdbp.general.common.biz.sequence.service;

import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.common.api.sequence.service.ILocalSequenceGenerator;
import com.gitee.qdbp.tools.specialized.SnowFlakeIdWorker;

/**
 * 使用TwitterSnowFlake生成序列号<br>
 * 多台服务器部署时必须要配置主机编号, 范围0~1023(共1024个节点)
 *
 * @author zhaohuihua
 */
// @Service
public class SnowFlakeIdSequenceGenerator implements ILocalSequenceGenerator {

    private final SnowFlakeIdWorker worker;

    /**
     * 构造函数
     * 
     * @param hostCode 主机编号
     */
    public SnowFlakeIdSequenceGenerator(int hostCode) {
        if (hostCode < 0 || hostCode > 1023) {
            throw new IllegalArgumentException("HostCode must be between 0 and 1023");
        }
        int workerId = hostCode % 32;
        int datacenterId = hostCode / 32;
        this.worker = new SnowFlakeIdWorker(workerId, datacenterId);
    }

    /**
     * 构造函数
     * 
     * @param epoch 初始时间, 项目最开始启用此序列号生成器的时间
     * @param hostCode 主机编号
     */
    public SnowFlakeIdSequenceGenerator(long epoch, int hostCode) {
        if (epoch < 0) {
            throw new IllegalArgumentException("epoch must be greater than 0");
        } else if (epoch > System.currentTimeMillis()) {
            throw new IllegalArgumentException("epoch must be less than current timestamp");
        }
        if (hostCode < 0 || hostCode > 1023) {
            throw new IllegalArgumentException("HostCode must be between 0 and 1023");
        }
        int workerId = hostCode % 32;
        int datacenterId = hostCode / 32;
        this.worker = new SnowFlakeIdWorker(epoch, workerId, datacenterId);
    }

    /**
     * 生成一个新的序号
     * 
     * @param type 类型
     * @param subtypes 子类型
     * @return 序号
     * @throws ServiceException
     */
    @Override
    public String generate(String type, String... subtypes) throws ServiceException {
        return String.valueOf(worker.nextId());
    }

}
